package svcnode.worker.netlog;

import java.io.File;
import java.io.FileWriter;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.SocketTimeoutException;

import net.sf.json.JSONObject;

import soar.basic.*;

import svcnode.share.*;

public class Netlog extends Thread
{
    private String __CLASS__=Netlog.class.getName();

    private DatagramSocket sock;

    public Netlog(DatagramSocket sock) throws Exception
    {/*{{{*/
        Cnfg cnfg=Cnfg.getInstance();
        String dir=cnfg.netlog.location;
        if(!cnfg.netlog.location.substring(0, 1).equals("/"))
            dir=(new File(".").getAbsolutePath())+"/"+dir;
        File d=new File(dir);
        if(d.exists())
        {
            if(!d.isDirectory() ||
                    !d.canRead() || !d.canWrite() || !d.canExecute())
            {
                System.err.println(__CLASS__+
                        ": netlog.location mode invalid");
                throw new Exception("netlog.location("+
                        cnfg.netlog.location+") invalid");
            }
        }
        else
        {
            if(!d.mkdir())
            {
                System.err.println(__CLASS__+
                        ": netlog.location mode invalid");
                throw new Exception("netlog.location("+
                        cnfg.netlog.location+") cannot create");
            }
        }

        this.sock=sock;
    }/*}}}*/

    public void run()
    {/*{{{*/
        final String __METHOD_="run";

        byte[] buf=new byte[1024];
        DatagramPacket p=new DatagramPacket(buf, buf.length);
        String ip;
        String request;

        try
        {
            this.sock.setSoTimeout(2*1000);
        }
        catch(Exception e)
        {
        }

        while(true)
        {
            ip=null;
            request=null;
            try
            {
                this.sock.receive(p);
                ip=p.getAddress().getHostAddress();
                request=new String(buf, 0, p.getLength());
            }
            catch(SocketTimeoutException e)
            {
                //System.out.println("%s.%s: receive timeout",
                //__CLASS__, __METHOD_);
            }
            catch(Exception e)
            {
                Errlog.add("%s.%s: receive fail: %s",
                        __CLASS__, __METHOD_, e.toString());
            }

            if(request != null)
            {
                callcmd(ip, request);
            }

            // 判断是否退出
            Operate operate=Operate.getInstance();
            if(operate.canShutdown())
            {
                operate.NetlogStop();
                Errlog.add("%s.%s: Netlog stop", __CLASS__, __METHOD_);
                break;
            }
        }
    }/*}}}*/

    private boolean callcmd(String ip, String request_s)
    {/*{{{*/
        try
        {
            JSONObject request=JSONObject.fromObject(request_s);
            if(!request.has("cmd"))
            {
                Errlog.add(__CLASS__+": request(%s) cmd not found",
                        request_s);
                return false;
            }
            String cmd=request.getString("cmd").toUpperCase();
            if(cmd.equals("LOG"))
            {
                if(!request.has("filename") || !request.has("msg"))
                {
                    Errlog.add(__CLASS__+": request(%s) format error",
                            request_s);
                    return false;
                }
                String filename=request.getString("filename");
                String msg=request.getString("msg");
                LOG(ip, filename, msg);
            }
            else
            {
                Errlog.add(__CLASS__+": request(%s) no cmd function",
                        request_s);
                return false;
            }
        }
        catch(Exception e)
        {
            Errlog.add(__CLASS__+": request(%s) invalid: %s",
                    request_s, e.toString());
            return false;
        }

        return true;
    }/*}}}*/

    private boolean LOG(String ip, String filename, String msg)
    {/*{{{*/
        Cnfg cnfg=Cnfg.getInstance();
        String dir=cnfg.netlog.location+"/"+ip;
        File d=new File(dir);
        if(d.exists())
        {
            if(!d.isDirectory() ||
                    !d.canRead() || !d.canWrite() || !d.canExecute())
            {
                Errlog.add(__CLASS__+": ip dir("+dir+") invalid");
                return false;
            }
        }
        else
        {
            if(!d.mkdir())
            {
                Errlog.add(__CLASS__+": create ip dir("+dir+") fail");
                return false;
            }
        }

        Date date=new Date();
        String file=dir+"/"+filename+".log."+
                    (new SimpleDateFormat("yyyyMMdd")).format(date);
        String date_s=(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss")).
            format(date);
        FileWriter log=null;
        try
        {
            log=new FileWriter(file, true);
            log.write(date_s+" -- "+msg+"\n");
        }
        catch(Exception e)
        {
            Errlog.add(__CLASS__+": write("+file+") fail:"+
                    e.toString());
            return false;
        }
        finally
        {
            try
            {
                if(log != null)
                    log.close();
            }
            catch(Exception e)
            {
                Errlog.add(__CLASS__+": close("+file+") fail:"+
                        e.toString());
                return false;
            }
        }

        return true;
    }/*}}}*/
}
